/** ********************************************************************** **\
	Fichier : serveur.cpp
	Projet  : JsVirtualWorldSrv
	Auteur  : J-S 'JSH676' Heid <js.heid@yahoo.fr>
	License : GPL
*** ********************************************************************** ***
	Copyright (C) 2009 J-S 'JSH676' Heid <js.heid@yahoo.fr>

	This file is part of JsVirtualWorldSrv.

	JsVirtualWorldSrv is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	JsVirtualWorldSrv is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with JsVirtualWorldSrv.  If not, see <http://www.gnu.org/licenses/>.
\** ********************************************************************** **/
#include "serveur.hpp"

Serveur::Serveur() {
	m_tailleMessage = 0;
	m_server = new QTcpServer(this);
	loadINI();
}

void Serveur::loadINI() {
	QSettings settings(_INI_FILE, QSettings::IniFormat);
	m_config["CONFIG/logging"]	= settings.value("CONFIG/logging").toString();
	m_config["CONFIG/logfile"]	= settings.value("CONFIG/logfile").toString();
	m_config["NET/port"]		= settings.value("NET/port", QVariant(_DEFAULT_PORT)).toString();
	m_config["DB/user"]			= settings.value("DB/user").toString();
	m_config["DB/pass"]			= settings.value("DB/pass").toString();
	m_config["DB/host"]			= settings.value("DB/host").toString();
	m_config["DB/base"]			= settings.value("DB/base").toString();
	m_config["LANG/cl_add"]		= settings.value("LANG/cl_add").toString();
	m_config["LANG/cl_del"]		= settings.value("LANG/cl_del").toString();
	m_config["COMMANDS/say"]	= settings.value("COMMANDS/say").toString();
}

void Serveur::openDB() {
	//m_db = QSqlDatabase::addDatabase("QSQLITE");
	//m_db.setHostName(m_config["DB/host"]);
	//m_db.setUserName(m_config["DB/user"]);
	//m_db.setPassword(m_config["DB/pass"]);
	//m_db.setDatabaseName(m_config["DB/base"]);
	//if (m_db->open()) {
	//	return true;
	//}
	//else {
	//	_PRINT_ERR("DB:Impossible de se connecter")
	//	return false;
	//}
}

void Serveur::listen() {
	if (!m_server->listen(_LISTEN, m_config["NET/port"].toInt())) {
		_PRINT_ERR("LISTEN:" + m_server->errorString().toStdString())
	}
	else {
		_PRINT("Le serveur ecoute sur le port "+m_config["NET/port"].toStdString())
		QObject::connect(m_server, SIGNAL(newConnection()), this, SLOT(net_addConnexion()));
	}
}




void Serveur::net_sendAll(const QString &message) {
	QByteArray paquet;
	QDataStream out(&paquet, QIODevice::WriteOnly);
	out << (quint16) 0;
	out << message;
	out.device()->seek(0);
	out << (quint16) (paquet.size() - sizeof(quint16));
	for (int i = 0; i < m_clients.size(); i++) {
		/// A FAIRE
		//m_clients[i].socket()->write(paquet);
	}
}

void Serveur::net_addConnexion() {
	net_sendAll(m_config["LANG/cl_add"]);
	QTcpSocket *nouveauClient = m_server->nextPendingConnection();
	User user(nouveauClient);
	m_clients.push_back(user);
	connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(net_recevoir()));
	connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(net_delConnexion()));
}

void Serveur::net_delConnexion() {
	net_sendAll(m_config["LANG/cl_quit"]);
	/// A CORRIGER :
	//QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
	//if (socket == 0) return;
	//User user(socket);
	//m_clients.removeOne(user);
	//socket->deleteLater();
}

void Serveur::net_recevoir() {
	QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
	if (socket == 0) return;
	QDataStream in(socket);
	if (m_tailleMessage == 0) {
		if (socket->bytesAvailable() < (int)sizeof(quint16)) return;
		in >> m_tailleMessage;
	}
	if (socket->bytesAvailable() < m_tailleMessage) return;
	QString message;
	in >> message;
	net_parseMessage(1, message, 1);
	m_tailleMessage = 0;
}







/// A FAIRE
void Serveur::net_parseMessage(int source, const QString &message, int senderId)
{
	// On parse le message et on l'envoi ....
	QRegExp parser(QString("^\\/([a-z]+) (.+)*$"), Qt::CaseSensitive, QRegExp::RegExp2);
	bool ok = parser.exactMatch(message);
	QStringList args = parser.capturedTexts();

	if (ok)
	{
		if (args[0] == m_config["COMMANDS/say"])
		{
			net_sendAll(args[1]);
		}
		else if (args[0] == m_config["COMMANDS/say"])
		{

		}
		else if (args[0] == m_config["COMMANDS/say"])
		{

		}
		else if (args[0] == m_config["COMMANDS/say"])
		{

		}
		else
		{

		}
	}
	else
	{
		// Message incorrect
	}
}
